/**
 * 
 */
package com.google.code.cisx.store.tx;

import com.google.code.cisx.store.api.StoreException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

/**
 * @author <a href='mailto:rahul.thakur.xdev@gmail.com'>Rahul Thakur</a>
 * @version $Id: TransactionInterceptor.java 22 2007-12-22 07:59:38Z
 *          rahul.thakur.xdev $
 * @since 1.0
 */
public class TransactionInterceptor implements MethodInterceptor {

  /**
   * Commons Logging.
   */
  private static final Log log = LogFactory.getLog(TransactionInterceptor.class);

  @Inject
  Provider<EntityManager> emProvider;

  /**
   * {@inheritDoc}
   * 
   * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
   */
  public Object invoke(MethodInvocation invocation) throws Throwable {
    if (log.isDebugEnabled())
      log.debug("Invoking interceptor : "
          + TransactionInterceptor.class.getName());
    Object result = null;
    EntityManager em = this.emProvider.get();
    EntityTransaction tx = em.getTransaction();
    try {
      tx.begin();
      // call the actual method
      result = invocation.proceed();      
      tx.commit();
    } catch (Exception e) {
      if (tx.isActive())
        tx.rollback();
      throw new StoreException(e);
    } finally {
      if (tx.isActive()) {
        em.flush();
        em.close();
      }
    }
    return result;
  }

}
